package com.zx.deploy.common.utils;

import java.io.File;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Security;
import java.util.Base64;

import javax.crypto.Cipher;

import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;

public  class  RSAUtil {

	//字符串进行加密算法的名称
	public static final String ALGORITHM = "RSA";
	//字符串进行加密填充的名称
	public static final String PADDING = "RSA/NONE/NoPadding";
	//字符串持有安全提供者的名称
	public static final String PROVIDER = "BC";
	//私钥文件路径(RSAUtil是RSA工具类的类名)
	public static final Resource PRIVATE_KEY_FILE = new ClassPathResource("build/pri.key"); 
	//公钥文件路径
	public static final  Resource PUBLIC_KEY_FILE = new ClassPathResource("build/pub.key");

	/**
	* 测试加密解密
	*/
	public void rsaTest(String str) {
	        System.out.println("[要加密解密的参数:{"+str+"}]");
	        try {
	            String cipherText = encrypt(str);
	            String plainText = decrypt(cipherText);
	            System.out.println("[加密后的参数为:{"+cipherText+"}]");
	            System.out.println("[解密后的参数为:{"+plainText+"}]");
	        } catch (Exception e) {
	        	 System.out.println("[RSA加密解密出现异常:{"+e+"}]");
	        }
	}

	/**
	 * 将字符串进行RSA加密
	 *
	 * @param text
	 * @return
	 */
	public static String encrypt(String text) {
	    String cipherTextBase64 = "";
	    try {
	        ObjectInputStream inputStream = new ObjectInputStream(PUBLIC_KEY_FILE.getInputStream());
	        PublicKey publicKey = (PublicKey) inputStream.readObject();
	        Security.addProvider(new BouncyCastleProvider());
	        Cipher cipher = Cipher.getInstance(PADDING, PROVIDER);
	        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
	        byte[] cipherText = cipher.doFinal(text.getBytes());
	        cipherTextBase64 = Base64.getEncoder().encodeToString(cipherText);
	    } catch (Exception e) {
	    	System.out.println("[字符串进行RSA加密出现异常:{"+ e+"}]");
	    }
	    return cipherTextBase64;
	}

	/**
	 * 将字符串进行RSA解密
	 *
	 * @param str
	 * @return
	 */
	public static String decrypt(String str) {
	    byte[] dectyptedText = null;
	    try {
	        ObjectInputStream inputStream = new ObjectInputStream(PRIVATE_KEY_FILE.getInputStream());
	        PrivateKey privateKey = (PrivateKey) inputStream.readObject();
	        Security.addProvider(new BouncyCastleProvider());
	        Cipher cipher = Cipher.getInstance(PADDING, PROVIDER);
	        cipher.init(Cipher.DECRYPT_MODE, privateKey);
	        byte[] text = Base64.getDecoder().decode(str);
	        dectyptedText = cipher.doFinal(text);
	    } catch (Exception e) {
	    	System.out.println("[字符串进行RSA解密出现异常:{"+e+"}]");
	    }
	    return new String(dectyptedText);
	}

	/**
	 * 判断秘钥文件是否存在
	 *
	 * @return
	 */
	public static boolean areKeysPresent() {
	    if (PRIVATE_KEY_FILE.exists() && PUBLIC_KEY_FILE.exists()) {
	        return true;
	    }
	    return false;
	}

	/**
	 * 生成公钥文件和私钥文件
	 */
	public static void generateKey() {
	    try {
	        Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
	        final KeyPairGenerator keyGen = KeyPairGenerator.getInstance(ALGORITHM, PROVIDER);
	        keyGen.initialize(1024);
	        final KeyPair key = keyGen.generateKeyPair();
	        File privateKeyFile = PRIVATE_KEY_FILE.getFile();
	        File publicKeyFile = PUBLIC_KEY_FILE.getFile();
	        if (privateKeyFile.getParentFile() != null) {
	            privateKeyFile.getParentFile().mkdirs();
	        }
	        privateKeyFile.createNewFile();
	        if (publicKeyFile.getParentFile() != null) {
	            publicKeyFile.getParentFile().mkdirs();
	        }
	        publicKeyFile.createNewFile();
	        ObjectOutputStream publicKeyOS = new ObjectOutputStream(new FileOutputStream(publicKeyFile));
	        publicKeyOS.writeObject(key.getPublic());
	        publicKeyOS.close();
	        ObjectOutputStream privateKeyOS = new ObjectOutputStream(new FileOutputStream(privateKeyFile));
	        privateKeyOS.writeObject(key.getPrivate());
	        privateKeyOS.close();
	    } catch (Exception e) {
	    	System.out.println("[生成公钥文件和私钥文件出现异常{"+e+"}]");
	    }
	}
	
	
	public static void main(String[] args) throws Exception {
		generateKey();
	}

	

}
